package com.maidou.qiantai.exception;

import com.maidou.qiantai.common.constant.HeritageSiteConstant;
import com.maidou.qiantai.exception.customizationException.AccessTokenAuthFailException;
import com.maidou.qiantai.exception.customizationException.DataLackException;
import com.maidou.qiantai.exception.customizationException.FailException;
import com.maidou.qiantai.exception.customizationException.RefreshTokenRefreshFailException;
import com.ruoyi.common.core.domain.AjaxResult;
import io.jsonwebtoken.JwtException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 异常统一处理
 *
 * @Author maidou
 * @Date 2023/4/26 12:00
 */
@RestControllerAdvice
public class ExceptionControllerAdvice extends BaseExceptionLogAdvice{
    /**
     * 自定义失败异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {FailException.class})
    public AjaxResult allFailExceptionAdvice(HttpServletRequest request, FailException e) throws Exception {
        logException(request, e, FailException.class);
        return AjaxResult.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    /**
     * 数据库数据缺失异常处理
     * @param request
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = {DataLackException.class})
    public AjaxResult dataLackExceptionAdvice(HttpServletRequest request, DataLackException e) throws Exception {
        logException(request, e, DataLackException.class);
        return AjaxResult.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    /**
     * 自定义access-token认证失败异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {AccessTokenAuthFailException.class, JwtException.class})
    public AjaxResult accessTokenAuthFailExceptionAdvice(HttpServletRequest request,AccessTokenAuthFailException e) {
        logException(request, e, AccessTokenAuthFailException.class);
        return AjaxResult.error(HttpStatus.UNAUTHORIZED.value(), e.getMessage());
    }

    /**
     * 自定义refresh-token刷新失败异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {RefreshTokenRefreshFailException.class})
    public AjaxResult refreshTokenRefreshFailExceptionAdvice(HttpServletRequest request, HttpServletResponse response, RefreshTokenRefreshFailException e) {
        logException(request, e, RefreshTokenRefreshFailException.class);
        response.setHeader(HeritageSiteConstant.JwtEnum.ACCESS_TOKEN.getValue(),"access");
        return AjaxResult.error(HttpStatus.FORBIDDEN.value(), e.getMessage());
    }


    /**
     * 服务器不支持请求数据的媒体格式，因此服务器拒绝请求。
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public AjaxResult bindExceptionHandler(HttpServletRequest request,BindException e) {
        String s = logException(request, e, BindException.class);
        return AjaxResult.error(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), s);
    }


    /**
     * 运行时所有异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {Exception.class})
    public AjaxResult allFailExceptionAdvice(HttpServletRequest request,Exception e) {
        String s = logException(request, e, Exception.class);
        return AjaxResult.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

}
